
#pragma once

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <cassert>

#include "inetaddr.h"

namespace sock {

	class AddrResolver {
		//const InetAddr & _addr;
		size_t _curpos;
		size_t _size;
		ADDRINFO * _pinfo;
		ADDRINFO * _pcurinfo;
	public:
		AddrResolver( const InetAddr & addr )
		{
			struct addrinfo *result = NULL, hints;
			int res = 0;

			ZeroMemory(&hints, sizeof (hints));
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			hints.ai_flags = AI_PASSIVE;

		
			const char * host = addr.host().empty() 
				? NULL : addr.host().c_str();
			res = ::getaddrinfo( host, addr.service().c_str(), &hints, &result);

			if ( res != 0 ) {
				throw SocketError( WSAGetLastError() );
			}
			ADDRINFO *ptr = result;
			while ( ptr != NULL ){
				++_size;
				ptr = ptr->ai_next;
			}
			_pinfo = result;
		}

		~AddrResolver() throw() { freeaddrinfo( _pinfo ); }

		size_t size() { return _size; }
		const ADDRINFO * operator[]( size_t pos )
		{
			assert( pos < _size );

			if( _curpos > pos ){
				rewind();
			}
			while( _curpos < _size && _curpos != pos ){
				next();
			}
			return _pcurinfo;
		}

	private:

		void next()
		{
			assert( _curpos < _size );
			assert( _pcurinfo );
			assert( _pinfo );

			_curpos++;
			_pcurinfo = _pcurinfo->ai_next;
		}

		void rewind()
		{
			_curpos = 0;
			_pcurinfo = _pinfo;
		}

	};
}